use std::any::Any;
use std::fmt;
use std::sync::Arc;

use tracing::{debug, error, info, warn};

use crate::actor::{PID, SystemMessage};
use crate::process::Process;
use crate::protos::remote::{MessageEnvelope, MessageHeader};
use crate::remote::{RemoteError, pid_to_proto};
use crate::remote::endpoint_manager::EndpointManager;
use uuid;

/// A process that represents a remote actor
pub struct RemoteProcess {
    /// The address of the remote actor system
    pub address: String,
    
    /// The ID of the remote actor
    pub id: String,
    
    /// Reference to the endpoint manager
    endpoint_manager: Arc<EndpointManager>,
}

impl RemoteProcess {
    /// Create a new remote process
    pub fn new(address: String, id: String, endpoint_manager: Arc<EndpointManager>) -> Self {
        Self {
            address,
            id,
            endpoint_manager,
        }
    }
    
    /// Get the full path of this remote actor
    pub fn path(&self) -> String {
        format!("{}/{}", self.address, self.id)
    }
}

impl fmt::Debug for RemoteProcess {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RemoteProcess")
            .field("address", &self.address)
            .field("id", &self.id)
            .finish()
    }
}

impl Process for RemoteProcess {
    fn send_user_message(&self, pid: &PID, message: Box<dyn Any + Send + Sync>) {
        // 创建一个临时的 PID 作为发送者
        let sender_pid = PID::new("nonhost".to_string(), uuid::Uuid::new_v4().to_string());
        
        // 调用 endpoint 的 send_message 方法
        if let Some(endpoint) = self.endpoint_manager.get_endpoint(&self.address) {
            endpoint.send_message(pid, &sender_pid, message);
        } else {
            warn!("Failed to send message: endpoint no longer exists");
        }
    }
    
    fn send_system_message(&self, pid: &PID, message: SystemMessage) {
        debug!(
            target = %pid,
            message_type = ?std::any::type_name::<SystemMessage>(),
            "Sending system message to remote actor"
        );
        
        // Handle system messages specially
        match message {
            SystemMessage::Watch(watcher_sender) => {
                // 创建一个PID来观察远程PID
                // 注意：Rust中的监视模式与Go版本有所不同
                // 我们需要转换sender -> PID逻辑
                let watcher_pid = PID::new("system", "watcher"); // 这是一个临时PID，实际实现需要能够正确标识发送者
                // 调用endpoint的watch方法
                if let Some(endpoint) = self.endpoint_manager.get_endpoint(&self.address) {
                    endpoint.watch(&watcher_pid, pid);
                }
            }
            SystemMessage::Unwatch(watcher_sender) => {
                // 类似于watch，但用于取消观察
                let watcher_pid = PID::new("system", "watcher"); // 临时PID
                // 调用endpoint的unwatch方法
                if let Some(endpoint) = self.endpoint_manager.get_endpoint(&self.address) {
                    endpoint.unwatch(&watcher_pid, pid);
                }
            }
            _ => {
                warn!(
                    target = %pid,
                    message_type = ?std::any::type_name::<SystemMessage>(),
                    "Unsupported system message type for remote actor"
                );
            }
        }
    }
    
    fn stop(&self, pid: &PID) {
        debug!(
            target = %pid,
            "Stopping remote actor"
        );
        
        // Send stop message to remote endpoint
        if let Some(endpoint) = self.endpoint_manager.get_endpoint(&self.address) {
            endpoint.stop();
        }
    }
} 